package com.mobimagic.lockscreen;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;

import com.mobimagic.lockscreen.activity.MobileChargingActivity;
import com.mobimagic.lockscreen.fullscreen.FullScreenCallBack;
import com.mobimagic.lockscreen.fullscreen.FullScreenDetector;
import com.mobimagic.lockscreen.remaintime.MobileChargingService;
import com.mobimagic.lockscreen.remaintime.StaticHandler;
import com.mobimagic.lockscreen.report.StatKey;
import com.mobimagic.lockscreen.report.Statistician2;
import com.mobimagic.lockscreen.sdk.ILockScreenHelper;
import com.mobimagic.lockscreen.sdk.LockScreenSDK;
import com.mobimagic.lockscreen.util.AppUtils;
import com.mobimagic.lockscreen.util.IntentSkip;
import com.mobimagic.lockscreen.util.SharedPref;
import com.mobimagic.lockscreen.view.FastChargeTipsActivity;
import com.mobimagic.lockscreen.view.MobileChargeColorHelper;
import com.qihoo.android.AndroidApiHelper;
import com.qihoo360.common.utils.Utils;
import com.qihoo360.mobilesafe.core.load.LoadProcessSituationFilter;
import com.qihoo360.mobilesafe.core.utils.GetTopPackageListsUtil;
import com.qihoo360.mobilesafe.core.utils.GetTopPackageUtil;
import com.qihoo360.mobilesafe.telephonyInterface.DualPhoneStateListener;
import com.qihoo360.mobilesafe.telephonyInterface.OperatorInterface;

public class MobileChargingHelper implements StaticHandler.MessageHandler, FullScreenCallBack {

    public static final boolean DEBUG = AppEnv.bAppdebug;

    public static MobileChargingHelper instance;
    public static final String TAG = "MobileChargingHelper";
    public static final String SECURITY_SERVICE_CREATE = "SecurityServiceCreate";
    private static final int MSG_SCREENON = 0;
    private static final int MSG_CHECK_TOP_APP = 2;
    private static final int MSG_SHOW_CHARGING = 3;

    private static final int BACKGROUND_MSG_INIT = 0;
    private static final int BACKGROUND_MSG_START_ACTIVITIES = 1;
    private static final int BACKGROUND_MSG_KILL_OTHERS = 2;
    private Context mContext;
    public Charge charge = new Charge();
    private boolean isScreenOn = true;
    private long lastFullTime = -1;

    private static final long ONE_HOUR = 60 * 60 * 1000;
    private static final long TIME_SEVEN_DAY = 7L * 24 * ONE_HOUR;
    private static final long WHEN_STOP_CHECK_TIME = 1 * 60 * 1000;
    /**
     * 如果上次充电充满的时间离当前时间太长，需要重置充满时间
     */
    public static final long LONGTIMENOSAVE = 3 * ONE_HOUR;
    /**
     * 插拔电源显示充电屏保界面不能小于1分钟
     */
    public static final long SHOW_MOBILE_CHARGE_INTERVAL_TIME = 1 * 60 * 1000;
    /**
     * 亮屏灭屏相邻两次显示充电屏保界面不能小于30秒
     */
    public static final long SHOW_MOBILE_CHARGE_INTERVAL_TIME_OTHER = 30 * 1000;
    public static final long DELAY_CHECK_OTHER_MOBILE_CHARGING_APPS = 3 * 1000;
    public static final int MAX_RECENTLY_PROCESS = 3;

    private int mV5Value;
    private boolean isCurrentClose;
    private PowerManager powerManager;
    private GetTopPackageUtil mGetTopPackageUtil;
    private GetTopPackageListsUtil mGetTopPackageListsUtil;
    private static final int STATE_DISCONNECT = 0;
    private static final int STATE_CONNECT = 1;
    /**
     * 0代表disconnect 1代表connect
     */
    private int connectState = STATE_DISCONNECT;
    private DualPhoneStateListener mCallPhoneStateListener;
    private int state = TelephonyManager.CALL_STATE_IDLE;
    private MobileChargeColorHelper colorHelper;
    private StaticHandler mStaticHandler;
    private Handler mBgHandler;
    private long stopTime;
    private Runnable clickTask;
    private long mChargingDestoryTime;
    private int mCheckFullScreenFrom = -1;
    private WeakReference<Activity> mChargingActivity;
    private final ActivityManager mAm;
    private PowerManager mPm;
    private ILockScreenHelper mLockScreenAdapter;
    private LockScreenSDK mLockScreenSDK;

    private MobileChargingHelper(final Context context) {
        mLockScreenSDK = LockScreenSDK.getInstance();
        mLockScreenAdapter = mLockScreenSDK.getLockScreenHelper();
        this.mContext = context;
        AlarmMatcher.initArams(context);
        mAm = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        mPm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        colorHelper = new MobileChargeColorHelper(context);
        powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        initConnectState(context);
        setScreenOn(powerManager.isScreenOn());
        mGetTopPackageListsUtil = new GetTopPackageListsUtil(mContext);
        mGetTopPackageUtil = new GetTopPackageUtil(mContext);
        mCompnentFilter.add(new ComponentName(mContext, MobileChargingActivity.class));
        mCallPhoneStateListener = new DualPhoneStateListener() {

            @Override
            public void onCallStateChanged(int state, String incomingNumber, int card) {
                MobileChargingHelper.this.state = state;

                switch (state) {
                case TelephonyManager.CALL_STATE_RINGING:
                    if (DEBUG) {
                        Log.i(TAG, "incoming call");
                    }
                    break;

                case TelephonyManager.CALL_STATE_IDLE:
                    if (DEBUG) {
                        Log.i(TAG, "phone stat idle");
                    }

                    break;

                case TelephonyManager.CALL_STATE_OFFHOOK:
                    if (DEBUG) {
                        Log.i(TAG, "call state offhook");
                    }
                    break;
                default:
                    if (DEBUG) {
                        Log.i(TAG, "ignore phone stat: " + state);
                    }

                    break;
                }
            }

        };
        mStaticHandler = new StaticHandler(this, Looper.getMainLooper());
        HandlerThread tr = new HandlerThread("mc");
        tr.start();
        mBgHandler = new Handler(tr.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                handleBgMessage(msg);
            }
        };
        // 仅在主进程注册这个监听
        if (mLockScreenAdapter.isDemoProcess()) {
            OperatorInterface.getDefault(LockScreenSDK.getInstance().getContext()).listen(mCallPhoneStateListener,
                    DualPhoneStateListener.LISTEN_CALL_STATE);
            mBgHandler.sendEmptyMessage(BACKGROUND_MSG_INIT);
        }
    }

    private void initBg() {
        if (DEBUG) {
            Log.i(TAG, "initBg()");
        }
        if (!powerManager.isScreenOn() || AndroidApiHelper.isKeyguardLocked(mContext, false)) {
            if (DEBUG) {
                Log.d(TAG, "fake screen off");
            }
            onScreenOff(false);
        }
    }

    private void handleBgMessage(Message msg) {
        if (DEBUG) {
            Log.i(TAG, "handle " + msg.what);
        }
        try {
            switch (msg.what) {
            case BACKGROUND_MSG_INIT: {
                initBg();
                break;
            }
            case BACKGROUND_MSG_START_ACTIVITIES: {
                List<Intent> intents = (List<Intent>) msg.obj;
                if (!intents.isEmpty()) {
                    if (DEBUG) {
                        Log.i("X", "start " + intents.get(0));
                    }
                    Message m = mBgHandler.obtainMessage(BACKGROUND_MSG_START_ACTIVITIES, intents);
                    mBgHandler.sendMessageDelayed(m, 300);
                    Intent next = intents.remove(0);
                    Statistician2.dbLog(StatKey.STATISTIC_MOBILE_CHARGING_PROTECT_SCREEN_STATE_WHEN_SWITCHING,
                            mPm.isScreenOn() ? "1" : "0", next.toString());
                    mContext.startActivity(next.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
                }
                break;
            }
            case BACKGROUND_MSG_KILL_OTHERS: {
                if (isOpenFastChargeFunc()) {
                    List<String> BeKillPkgs = mLockScreenAdapter.get2BeKillPkgs();
                    for (String other : BeKillPkgs) {
                        mAm.killBackgroundProcesses(other);
                    }
                }
            }
            }
        } catch (Exception e) {
            if (DEBUG) {
                Log.e(TAG, "", e);
            }
        }

    }

    public void setChargingActivity(Activity activity) {
        mChargingActivity = new WeakReference<Activity>(activity);
    }

    public Activity getChargingActivity() {
        if (mChargingActivity != null) {
            Activity activity = mChargingActivity.get();
            if (activity == null || activity.isFinishing()) {
                return null;
            }
            return activity;
        }
        return null;
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case MSG_SCREENON:
            long delta = Math.abs(mChargingDestoryTime - System.currentTimeMillis());
            //为了避免用户亮屏3秒内打开广告或是退出充电界面，此时不应该和竞品去争，因为是用户操作
            boolean userDestoryChargingAcitivity = delta < DELAY_CHECK_OTHER_MOBILE_CHARGING_APPS;
            if (DEBUG) {
                Log.d(TAG, "handleMessage.MSG_SCREENON.isOtherMobileCharging=" + isOtherMobileCharging()
                        + "userDestoryChargingAcitivity=" + userDestoryChargingAcitivity);
            }
            if (DEBUG) {
                Log.d(TAG, "亮屏延时3秒竟品判断.charging=" + charge.isCharging() + "isopenFastChangeFuc()"
                        + isOpenFastChargeFunc() + " state=" + this.state);
            }
            if (userDestoryChargingAcitivity) {
                if (DEBUG) {
                    Log.d(TAG, "handleMessage.MSG_SCREENON用户人为操作退出充电屏保，无需做任何操作");
                }
                return;
            }
            Activity activity = getChargingActivity();
            int from = MobileChargingActivity.EXTRA_FROM_OTHER_CHARGING_APP_SCREEN_ON;
            //说明充电屏保已经存在
            if (activity != null) {
                List<String> topProcess = getTopProcess(MAX_RECENTLY_PROCESS);
                boolean isCurrentAlarm = AlarmMatcher.isCurrentAlarm();
                if (isCurrentAlarm) {
                    finishChargingActivity(activity, AlarmMatcher.alarmToString());
                    return;
                }
                for (String topAppPak : topProcess) {
                    if (!TextUtils.isEmpty(topAppPak) && !mLockScreenAdapter.getAlarmPkgs().contains(topAppPak)
                            && isClockOrAlarmApp(topAppPak)) {
                        finishChargingActivity(activity, topAppPak);
                        return;
                    }
                }
                if (!charge.isCharging() || this.state != TelephonyManager.CALL_STATE_IDLE) {
                    return;
                }
                if (isOtherMobileCharging() && isOpenFastChargeFunc()) {
                    if (DEBUG) {
                        Log.i(TAG, "亮屏弹");
                    }
                    IntentSkip.skipToBatteryCharging(mContext, from);
                }
            } else {
                if (!charge.isCharging() || this.state != TelephonyManager.CALL_STATE_IDLE) {
                    return;
                }

                if (isOtherMobileCharging() && isOpenFastChargeFunc()) {
                    if (DEBUG) {
                        Log.i(TAG, "亮屏弹");
                    }

                    if (!alarmReject(from)) {
                        IntentSkip.skipToBatteryCharging(mContext, from);
                    }
                }
            }
            //在最后判断是否开启引导弹窗或是强制开启逻辑，避免当次强制开启后，立马打开充电屏保
            checkIsForcedOpenOrShowGuideDialog(charge.isCharging(), AppUtils.isAtLanucher(mContext));

            break;

        case MSG_CHECK_TOP_APP:
            checkShowTop();
            checkSendMessage();
            break;
        case MSG_SHOW_CHARGING:
            showCharging(msg.arg1);
            break;
        }

    }

    void init() {
        if (!powerManager.isScreenOn() /* || */) {
            if (DEBUG) {
                Log.d(TAG, "screen is off");
            }
            onScreenOff(false);
        }
    }

    private void finishChargingActivity(Activity activity, String topAppPak) {
        if (DEBUG) {
            Log.d(TAG, "高屏时，充电屏保还存在，且有闹钟 pkg=" + topAppPak);
        }
        Statistician2.dbLog(StatKey.STATISTIC_MOBILE_CHARGING_CLOCK_APP,
                String.valueOf(MobileChargingActivity.EXTRA_FROM_CHECK_ALARM_SCREEN_ON), topAppPak);
        activity.finish();
    }

    private void initConnectState(Context context) {
        IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        Intent intent = context.registerReceiver(null, ifilter);

        if (intent == null) {
            if (DEBUG) {
                Log.e(TAG, "获取电量状态失败");
            }
            return;
        }
        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        boolean isFull = status == BatteryManager.BATTERY_STATUS_FULL;
        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || isFull;
        connectState = isCharging ? STATE_CONNECT : STATE_DISCONNECT;
        if (DEBUG) {
            Log.d(TAG, "initConnectState connectState=" + connectState);
        }

    }

    public MobileChargeColorHelper getColorHelper() {
        return colorHelper;
    }

    private void setScreenOn(boolean screenOn) {
        if (DEBUG) {
            Log.d(TAG, "setScreenOn" + screenOn);
        }
        this.isScreenOn = screenOn;
    }

    public void onScreenOn(boolean isBegin) {
        if (isBegin) {
            return;
        }
        refreshChage();
        AlarmMatcher.refreshAlarm(mContext);
        if (DEBUG) {
            Log.d(TAG, "onScreenOn");
        }
        setScreenOn(true);
        Statistician2.dbLog(StatKey.STATISTIC_MOBILE_CHARGE_SCREEN_ON);

        mStaticHandler.removeMessages(MSG_CHECK_TOP_APP);
        mStaticHandler.sendEmptyMessageDelayed(MSG_SCREENON, DELAY_CHECK_OTHER_MOBILE_CHARGING_APPS);
    }

    public String getTop5AppName() {
        return mGetTopPackageListsUtil.getTopPackageListsName(5);
    }

    private boolean isOtherMobileCharging() {
        String appPkg = mGetTopPackageUtil.getTopPackageName();
        if (DEBUG) {
            Log.d(TAG, "isOtherMobileCharging.appPkg=" + appPkg);
        }
        if (!TextUtils.isEmpty(appPkg)) {
            List<String> mOtherChargingPkgs = mLockScreenAdapter.getOtherLockScreenPkgs();
            for (String otherPkg : mOtherChargingPkgs) {
                if (TextUtils.isEmpty(otherPkg)) {
                    continue;
                }
                if (otherPkg.contains(appPkg) || appPkg.contains(otherPkg)) {
                    return true;
                }
            }
        }
        return false;
    }

    public Runnable getClickTask() {
        return clickTask;
    }

    public void setClickTask(Runnable clickTask) {
        this.clickTask = clickTask;
    }

    public void onUserPresent() {
        if (clickTask != null) {
            clickTask.run();
            clickTask = null;
        }

    }

    public void onShowButScreenOff() {
        refreshChage();
        stopTime = System.currentTimeMillis();
        if (DEBUG) {
            Log.d(TAG, "onShowButScreenOff.");
        }
        checkSendMessage();

    }

    private void checkSendMessage() {
        boolean needCheck = stopTime > 0 && Math.abs(System.currentTimeMillis() - stopTime) < WHEN_STOP_CHECK_TIME;
        if (DEBUG) {
            Log.d(TAG, "checkSendMessage.needCheck=" + needCheck);
        }
        if (!needCheck) {
            return;
        }
        boolean isScreenOn = powerManager.isScreenOn();
        if (isCharging() && !isScreenOn) {
            if (DEBUG) {
                Log.d(TAG, "checkSendMessage.3秒后需要做判断");
            }
            mStaticHandler.removeMessages(MSG_CHECK_TOP_APP);
            mStaticHandler.sendEmptyMessageDelayed(MSG_CHECK_TOP_APP, 3000);
        }
    }

    private void checkShowTop() {
        List<String> others = mLockScreenAdapter.getOtherLockScreenPkgs();
        if (DEBUG) {
            Log.d(TAG, "checkShowTop.");
            Log.i(TAG, "Other:" + others);
        }
        boolean isScreenOn = powerManager.isScreenOn();
        String topApp = mGetTopPackageUtil.getTopPackageName();
        if (DEBUG) {
            Log.d(TAG,
                    "onShowButScreenOff.topApp=" + topApp + " isScreenOn=" + isScreenOn + " isCharging="
                            + charge.isCharging());
        }
        if (!charge.isCharging()) {
            return;
        }
        if (!isScreenOn && !TextUtils.isEmpty(topApp) && others.contains(topApp)) {

            if (DEBUG) {
                Log.d(TAG, "onShowButScreenOff.至顶！");
            }

            int from = MobileChargingActivity.EXTRA_FROM_OTHER_CHARGING_APP_SCREEN_OFF;
            if (!alarmReject(from)) {
                IntentSkip.skipToBatteryCharging(mContext, from);
            }

        }
    }

    public void refreshChage() {
        getCharge(mContext, charge);
    }

    public void onScreenOff(boolean atHome) {
        if (DEBUG) {
            Log.d(TAG, "onScreenOff atHome=");
        }
        refreshChage();
        setScreenOn(false);
        AlarmMatcher.refreshAlarm(mContext);
        mStaticHandler.removeMessages(MSG_SCREENON);
        Statistician2.dbLog(StatKey.STATISTIC_MOBILE_CHARGE_SCREEN_OFF);
        if (!charge.isCharging() || this.state != TelephonyManager.CALL_STATE_IDLE) {
            return;
        }
        if (DEBUG) {
            Log.d(TAG, "灭屏 isScreenOn" + isScreenOn + "phoneState=" + state);
        }
        //2016/2/19 灭屏强弹
        if (DEBUG) {
            Log.i(TAG, "isScreenNeedShow=" + isScreenOnOrOffNeedShowBatCha());
        }
        if (isScreenOnOrOffNeedShowBatCha()) {

            if (DEBUG) {
                Log.i(TAG, "灭屏弹");
            }
            if (isOpenFastChargeFunc()) {
                rejectIfFullScreenOrAlarm(MobileChargingActivity.EXTRA_FROM_SCREENOFF);
            } else {
                if (DEBUG) {
                    Log.i(TAG, "boost charge not open");
                }
            }

        }
        checkIsForcedOpenOrShowGuideDialog(charge.isCharging(), AppUtils.isAtLanucher(mContext));
    }

    /**
     * 获取当前是否是横屏,是横屏则不弹充电屏保
     */
    public boolean isCurScreenLandscape() {
        Configuration config = mContext.getResources().getConfiguration();
        int ori = config.orientation;
        if (DEBUG) {
            Log.i(TAG, "ori==" + ori);
        }
        if (ori == config.ORIENTATION_LANDSCAPE) {
            return true;
        }
        return false;
    }

    public String getTopAppPackageName() {
        return mGetTopPackageUtil.getTopPackageName();
    }

    public void onBatteryStatusChange(Intent intent) {
        if (!mLockScreenAdapter.isDemoProcess()) {
            return;
        }
        getCharge(mContext, charge);
        AlarmMatcher.refreshAlarm(mContext);
        String action = intent.getAction();
        if (DEBUG) {
            Log.d(TAG, "收到手机充电广播action=" + intent.getAction());
        }

        if (DEBUG) {
            boolean isNeedShowBatteryCharge = isNeedShowBatteryCharge();
            Log.i(TAG, "isNeedShowBatteryCharge==" + isNeedShowBatteryCharge);
        }
        if (Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
            if (DEBUG) {
                Log.d(TAG, "断开数据线connectState=" + connectState + "state=" + state);
            }
            Statistician2.dbLog(StatKey.STATISTIC_MOBILE_CHARGE_POWER_DISCONNECT, charge.getChargingValue() + "",
                    System.currentTimeMillis() + "");
            if (this.connectState == STATE_DISCONNECT || this.state != TelephonyManager.CALL_STATE_IDLE) {
                return;
            }
            if (DEBUG) {
                Log.i(TAG, "isNeedShowBatteryCharge()==" + isNeedShowBatteryCharge() + "!isCurScreenLandscape()=="
                        + !isCurScreenLandscape());
            }
            if (isNeedShowBatteryCharge() && isOpenFastChargeFunc() && !isCurScreenLandscape()) {
                if (DEBUG) {
                    Log.i(TAG, "拔电源弹");
                }
                rejectIfFullScreenOrAlarm(MobileChargingActivity.EXTRA_FROM_DISCONNECT);
            }
            this.connectState = STATE_DISCONNECT;
        }
        if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
            this.connectState = STATE_CONNECT;
            Statistician2.dbLog(StatKey.STATISTIC_MOBILE_CHARGE_POWER_CONNECT, charge.getChargingValue() + "",
                    System.currentTimeMillis() + "");
            if (DEBUG) {
                boolean isOpen = isOpenFastChargeFunc();
                Log.d(TAG, "连上数据线 connectState=" + connectState + "isOpen:" + isOpen + "state=" + state);
            }
            if (this.state != TelephonyManager.CALL_STATE_IDLE) {
                return;
            }
            boolean isScreenOn = powerManager.isScreenOn();
            if (DEBUG) {
                Log.i(TAG, "isNeedShow==" + isNeedShowBatteryCharge() + "osSreenOn=" + isScreenOn + "!isLandscape=="
                        + !isCurScreenLandscape());
            }
            if (isNeedShowBatteryCharge() && isScreenOn && isOpenFastChargeFunc() && !isCurScreenLandscape()) {
                if (DEBUG) {
                    Log.i(TAG, "插电弹");
                }
                rejectIfFullScreenOrAlarm(MobileChargingActivity.EXTRA_FROM_CONNECT);

            }
            checkIsForcedOpenOrShowGuideDialog(true, AppUtils.isAtLanucher(mContext));
        }

    }

    /**
     * 记录亮屏灭屏显示充电屏保时间
     */
    public void setScreenOnOrOffInterTime() {
        SharedPref.setLong(mContext, SharedPref.SCREEN_ON_OR_SCREEN_OFF_FAST_CHARGE_LAST_SHOW_TIME,
                System.currentTimeMillis());
    }

    /**
     * 亮屏灭屏相邻两次之间是否大于1分钟
     */
    public boolean isScreenOnOrOffNeedShowBatCha() {
        boolean isNeedShow = false;
        long lastShowTime = SharedPref.getLong(mContext, SharedPref.SCREEN_ON_OR_SCREEN_OFF_FAST_CHARGE_LAST_SHOW_TIME,
                0L);
        long intervalTime = Math.abs(System.currentTimeMillis() - lastShowTime);
        if (intervalTime > SHOW_MOBILE_CHARGE_INTERVAL_TIME_OTHER) {
            isNeedShow = true;
        } else {
            isNeedShow = false;
        }
        if (DEBUG) {
            Log.i(TAG, "isNeedShow==" + isNeedShow);
        }
        return isNeedShow;
    }

    /**
     * 记录插拔电源时间
     */
    public void setIntervalTime() {
        SharedPref.setLong(mContext, SharedPref.CONNECT_OR_DISCONNECT_POWER_FAST_CHARGE_LAST_SHOW_TIME,
                System.currentTimeMillis());
    }

    /**
     * 插拔电源相邻两次之间的时间间隔大于10分钟才弹
     */
    public boolean isNeedShowBatteryCharge() {
        boolean isNeedShow = false;
        long lastShowTime = SharedPref.getLong(mContext,
                SharedPref.CONNECT_OR_DISCONNECT_POWER_FAST_CHARGE_LAST_SHOW_TIME, 0L);
        long intervalTime = Math.abs(System.currentTimeMillis() - lastShowTime);
        if (intervalTime > SHOW_MOBILE_CHARGE_INTERVAL_TIME) {
            isNeedShow = true;
        } else {
            isNeedShow = false;
        }
        if (DEBUG) {
            Log.i(TAG, "isNeedShow==" + isNeedShow);
        }
        return isNeedShow;
    }

    /**
     * 是否第一次进入充电屏保界面
     */
    public boolean isFirstEntCharge() {
        boolean theFirstEnter;
        boolean theFirstCondition = SharedPref.getBoolean(mContext, SharedPref.THE_FIRST_START_CHARGING_CONDITION,
                false);//第一次启动屏保界面判断的条件
        if (!theFirstCondition) {
            theFirstEnter = true;
            SharedPref.setBoolean(mContext, SharedPref.THE_FIRST_START_CHARGING_CONDITION, true);
        } else {
            theFirstEnter = false;
        }
        if (DEBUG) {
            Log.i(TAG, "theFirstEnter==" + theFirstEnter);
        }
        return theFirstEnter;
    }

    /**
     * 是否需要强制开启快速充电
     * 1:下发v5配置为2
     * 2:默认为关，非用户关闭过的。
     * 3:正在充电
     */
    public boolean isNeedForcedOpen() {
        if (DEBUG) {
            Log.i(TAG, "mV5Value==" + mV5Value + "isDefaultClose==" + isCurrentClose + "mIsCharging==" + isCharging()
                    + "!isUserCloseFastChargeFunc()==" + !isUserCloseFastChargeFunc());
        }
        return (mV5Value == 2) && isCurrentClose && !isUserCloseFastChargeFunc() && isCharging();
    }

    /**
     * 检查是否需要强制开启充电功能或是开启引导弹窗
     */
    public boolean checkIsForcedOpenOrShowGuideDialog(boolean isCharging, boolean atHome) {
        refreshChage();
        int value = mLockScreenAdapter.getChargeTipsType();
        if (DEBUG) {
            Log.i(TAG, "v5Value==" + value + "isCharging=" + isCharging + "atHome=" + atHome);
        }
        if (value == 1 || value == 2) {
            mV5Value = value;
            isCurrentClose = !isOpenFastChargeFunc();
            if (isNeedForcedOpen()) {
                MobileChargingHelper.getInstance().setOpenFastChargeFunc(true);
                return true;
            }
            if (checkIsNeedShowGuideDialog(value, isCharging, atHome)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 检查是否需要显示引导弹窗
     * 
     * @param value
     *            v5文件读取的值
     * @param isCharging
     *            是否正在充电中
     * @param atHome
     *            是否在主界面
     * @return
     */
    public boolean checkIsNeedShowGuideDialog(int value, boolean isCharging, boolean atHome) {
        if (value == 1 && !isOpenFastChargeFunc() && isCharging && atHome) {
            int clickTimes = SharedPref.getInt(mContext, SharedPref.FAST_CHARGE_GUIDE_DIALOG_DISPLAY_TIMES, 0);
            long lastDisplayTime = SharedPref.getLong(mContext, SharedPref.FAST_CHARGE_GUIDE_DIALOG_LAST_DISPLAY_TIME,
                    0L);
            long dTime = System.currentTimeMillis() - lastDisplayTime;
            if (DEBUG) {
                Log.i(TAG, "clickTimes==" + clickTimes + "lastDisplayTime==" + lastDisplayTime);
            }
            if (clickTimes < 3 && dTime > TIME_SEVEN_DAY) {
                IntentSkip.skipToFastChargeTipsActivity(mContext, FastChargeTipsActivity.OPEN_FAST_CHARGE_GUIDE_DIALOG);
                return true;
            }
        }
        return false;
    }

    public static void getCharge(Context context, Charge charge) {
        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        Intent intent = context.registerReceiver(null, intentFilter);
        if (intent == null) {
            if (DEBUG) {
                Log.e(TAG, "获取电量状态失败");
            }
            return;
        }
        getCharge(intent, charge);
    }

    public static void getCharge(Intent intent, Charge charge) {
        //当前剩余电量
        int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
        //电量最大值
        int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
        float batteryPct = level / (float) scale;
        boolean isReal = true;
        if (batteryPct < 0) {
            batteryPct = 0.5f;
            isReal = false;
        } else if (batteryPct > 1) {
            batteryPct = 0.5f;
            isReal = false;
        }
        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);

        boolean isFull = status == BatteryManager.BATTERY_STATUS_FULL;
        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || isFull;
        int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
        Charge.ChargingType chargeType = null;
        if (chargePlug == BatteryManager.BATTERY_PLUGGED_USB) {
            chargeType = Charge.ChargingType.USB;
        } else if (chargePlug == BatteryManager.BATTERY_PLUGGED_AC) {

            chargeType = Charge.ChargingType.AC;
        }
        isCharging = isCharging || chargeType != null;
        charge.setCharging(isCharging);
        charge.setChargingType(chargeType);
        charge.setChargingValueAndCalc(batteryPct, isReal);
        boolean chargeFull = charge.isFull();
        boolean nowFull = isFull || batteryPct == 1;
        long lastfull = getInstance().getLastFullTime();
        long current = System.currentTimeMillis();
        if (nowFull && !chargeFull) {
            if (lastfull <= 0 || lastfull + LONGTIMENOSAVE < current || lastfull > current) {
                getInstance().saveLastFullTime(current);
            }
        } else if (!nowFull && chargeFull) {
            getInstance().saveLastFullTime(0);
        } else if (!nowFull && !chargeFull) {
            if (lastfull > 0) {
                getInstance().saveLastFullTime(0);
            }

        } else {
            if (lastfull <= 0 || lastfull > current) {
                getInstance().saveLastFullTime(System.currentTimeMillis());
            }
        }
        charge.setFull(nowFull);
        charge.setFullTime(getInstance().lastFullTime);
        if (DEBUG) {
            Log.d(TAG, String.format("level=%s,scale=%s,batteryPct=%s,isFull=%s", level, scale, batteryPct, isFull));
            Log.d(TAG, String.format("status=%s,isCharging=%s,chargeType=%s", status, isCharging, chargeType));
        }
    }

    private void saveLastFullTime(long time) {
        this.lastFullTime = time;
        SharedPref.setLong(mContext, SharedPref.MOBILE_CHARGING_LAST_FULL_TIME, time);
    }

    private long getLastFullTime() {
        if (lastFullTime == -1) {
            //保证第一次被读过
            lastFullTime = readLastFullTime();
        }
        return lastFullTime;
    }

    private long readLastFullTime() {
        return SharedPref.getLong(mContext, SharedPref.MOBILE_CHARGING_LAST_FULL_TIME, 0);
    }

    public synchronized static MobileChargingHelper getInstance() {
        if (instance == null) {
            instance = new MobileChargingHelper(LockScreenSDK.getInstance().getContext());
        }
        return instance;

    }

    /**
     * 是否需要展示加速完成页的快速充电卡片
     */
    public boolean isNeedShowFastChargeCard() {
        boolean isFastChargeOpen = SharedPref
                .getBoolean(mContext, SharedPref.FAST_CHARGE_FUNCTION_SWITCH_STATUS, false);
        return !isFastChargeOpen;
    }

    public boolean isNeedShowFastChargeCardFirst() {
        return (charge.getChargingValue() < 0.5f || charge.isCharging());
    }

    public boolean isCharging() {
        return charge.isCharging();
    }

    /**
     * 设置是否打开快速充电功能
     * true 打开
     * false 关闭
     */
    public void setOpenFastChargeFunc(boolean open) {
        SharedPref.setBoolean(mContext, SharedPref.FAST_CHARGE_FUNCTION_SWITCH_STATUS, open);
    }

    /**
     * 是否用户关闭快速充电功能
     */
    public void setUserCloseFastChargeFunc(boolean close) {
        SharedPref.setBoolean(mContext, SharedPref.IS_USER_TAKE_THE_INITIATIVE_TO_CLOSE, close);
    }

    public boolean isUserCloseFastChargeFunc() {
        return SharedPref.getBoolean(mContext, SharedPref.IS_USER_TAKE_THE_INITIATIVE_TO_CLOSE, false);
    }

    public boolean isOpenFastChargeFunc() {
        return SharedPref.getBoolean(mContext, SharedPref.FAST_CHARGE_FUNCTION_SWITCH_STATUS, false);
    }

    public String getBoostedStr() {
        int value = (int) (10 + Math.random() * 10);
        return String.valueOf(value);
    }

    public void startChargingServiceIfNeed(String action, Bundle bundle) {

        boolean isOpenFastCharge = isOpenFastChargeFunc();
        if (DEBUG) {
            Log.d(TAG, "startChargingServiceIfNeed().isOpenFastCharge=" + isOpenFastCharge + " action=" + action);
        }
        if (isOpenFastCharge) {
            Intent intent = new Intent(mContext, MobileChargingService.class);
            if (bundle == null) {
                bundle = new Bundle();
            }
            bundle.putString(MobileChargingService.INTENT_ACTION, action);
            intent.putExtras(bundle);
            mContext.startService(intent);
        }
    }

    public void onChargingDestory() {
        removeScreenOnMeesage();
        if (mChargingActivity != null) {
            mChargingActivity.clear();
            mChargingActivity = null;
        }
    }

    public void removeScreenOnMeesage() {
        mStaticHandler.removeMessages(MSG_SCREENON);
        mChargingDestoryTime = System.currentTimeMillis();
    }

    /**
     * 是否是闹钟类应用
     */
    public boolean isClockOrAlarmApp(String pakName) {
        if (TextUtils.isEmpty(pakName)) {
            return false;
        }
        List<String> lists = ClockAppReaderHelper.getInstance().getClockList();
        if (DEBUG) {
            Log.i(TAG, "lists==" + lists);
        }
        if (LoadProcessSituationFilter.isALarmPackage(pakName)) {
            return true;
        }
        if (lists != null && lists.size() != 0) {
            return lists.contains(pakName);
        }
        return false;
    }

    public List<String> getTopProcess(int size) {
        long time = System.currentTimeMillis();
        List<String> topProcess = new ArrayList<String>();
        List<String> homes = Utils.getHomeLauncherPackages(mContext);
        LinkedHashSet<String> recent = mGetTopPackageListsUtil.getTopPackageLists(size);
        List<String> list = new ArrayList<String>();
        list.addAll(recent);
        int index = list.size() - 1;
        for (String home : homes) {
            int findIndex = list.indexOf(home);
            if (findIndex > -1) {
                index = findIndex - 1;
                break;
            }
        }
        for (int i = 0; i <= index; i++) {
            topProcess.add(list.get(i));
        }

        if (DEBUG) {
            long wastTime = System.currentTimeMillis() - time;
            Log.d(TAG, "getTopProcess.topProcess=" + topProcess + "wastTime=" + wastTime);
        }

        return topProcess;
    }

    private boolean alarmReject(int from) {
        if (AlarmMatcher.isCurrentAlarm()) {
            if (DEBUG) {
                Log.d(TAG, "alarmReject. 当前时间有闹钟，所以不弹");
            }
            Statistician2.dbLog(StatKey.STATISTIC_MOBILE_CHARGING_SYS_CLOCK, AlarmMatcher.alarmToString(),
                    AlarmMatcher.currentTimeString());
            return true;
        }
        List<String> topProcess = getTopProcess(MAX_RECENTLY_PROCESS);
        List<String> alarms = mLockScreenAdapter.getAlarmPkgs();
        for (String topAppPak : topProcess) {
            if (!TextUtils.isEmpty(topAppPak) && !alarms.contains(topAppPak) && isClockOrAlarmApp(topAppPak)) {
                if (DEBUG) {
                    Log.d(TAG, "alarmReject.顶层是闹钟应用");
                }
                Statistician2.dbLog(StatKey.STATISTIC_MOBILE_CHARGING_CLOCK_APP, String.valueOf(from), topAppPak);
                return true;
            }
        }
        return false;

    }

    private void rejectIfFullScreenOrAlarm(int from) {
        if (DEBUG) {
            Log.d(TAG, "rejectIfFullScreenOrAlarm. from=" + from);
        }

        boolean alarmReject = alarmReject(from);
        if (alarmReject) {
            if (DEBUG) {
                Log.d(TAG, "rejectIfFullScreenOrAlarm.alarmReject=" + alarmReject);
            }
            return;
        }
        switch (from) {
        case MobileChargingActivity.EXTRA_FROM_CONNECT:
        case MobileChargingActivity.EXTRA_FROM_DISCONNECT:
            FullScreenDetector.checkFullScreen(mContext, this);
            mCheckFullScreenFrom = from;
            break;
        case MobileChargingActivity.EXTRA_FROM_SCREENOFF:
        case MobileChargingActivity.EXTRA_FROM_OTHER_CHARGING_APP_SCREEN_OFF:
            List<String> otherApps = mLockScreenAdapter.getOtherLockScreenPkgs();
            if (otherApps.isEmpty()) {
                Statistician2.dbLog(StatKey.STATISTIC_MOBILE_CHARGING_PROTECT_CASE, "0", "");
                IntentSkip.skipToBatteryCharging(mContext, from);
            } else {
                Message m = mStaticHandler.obtainMessage(MSG_SHOW_CHARGING, from, 0);
                mStaticHandler.sendMessageDelayed(m, 2000);
            }
            setScreenOnOrOffInterTime();
            break;
        default:
            IntentSkip.skipToBatteryCharging(mContext, from);
        }

    }

    private Set<ComponentName> mCompnentFilter = new HashSet<ComponentName>();

    private void showCharging(int from) {
        Intent homeIntent = new Intent(Intent.ACTION_MAIN);
        homeIntent.addCategory(Intent.CATEGORY_HOME);
        ComponentName home = AndroidApiHelper.getBestActivity(mContext, homeIntent);
        if (home != null) {
            homeIntent.setComponent(home);
            List<String> otherLockScreens = mLockScreenAdapter.getOtherLockScreenPkgs();
            Set<String> others = new HashSet<String>();
            others.addAll(otherLockScreens);
            ComponentName other = AndroidApiHelper.getLastUsedActivity(mContext, others, mCompnentFilter);
            if (other != null) {
                mBgHandler.removeMessages(BACKGROUND_MSG_START_ACTIVITIES);
                if (!AndroidApiHelper.checkComponentPermission(mContext, other)) {
                    if (DEBUG) {
                        Log.i("X", other + " not exported");
                    }
                    Statistician2.dbLog(StatKey.STATISTIC_MOBILE_CHARGING_PROTECT_CASE, "1", "1", other.toString());
                    IntentSkip.skipToBatteryCharging(mContext, from);
                    return;
                }
                Statistician2.dbLog(StatKey.STATISTIC_MOBILE_CHARGING_PROTECT_CASE, "2", home.toString(),
                        other.toString());
                List<Intent> intents = new ArrayList<Intent>();
                intents.add(homeIntent);
                if (!other.equals(home)) {
                    Intent otherIntent = new Intent();
                    //otherIntent.setClass(mContext, ForwardActivity.class);
                    //otherIntent.putExtra(ForwardActivity.EXTRA_TARGET, other);
                    otherIntent.setComponent(other);
                    otherIntent.addCategory(Intent.CATEGORY_LAUNCHER);
                    otherIntent.setAction(Intent.ACTION_MAIN);
                    intents.add(otherIntent);
                }
                Intent intent = new Intent(mContext, MobileChargingActivity.class);
                intent.putExtra(MobileChargingActivity.EXTRA_FROM, from);
                intents.add(intent);
                if (DEBUG) {
                    Log.i("X", "intents:" + intents);
                }
                mBgHandler.sendMessage(mBgHandler.obtainMessage(BACKGROUND_MSG_START_ACTIVITIES, intents));
                return;
            }
        }
        Statistician2.dbLog(StatKey.STATISTIC_MOBILE_CHARGING_PROTECT_CASE, "1", "0");
        IntentSkip.skipToBatteryCharging(mContext, from);
    }

    @Override
    public void onFullScreenDetected(int type) {
        switch (type) {
        case FULLSCREEN_TYPE:
            String topPkg = mGetTopPackageUtil.getTopPackageName();
            Statistician2.dbLog(StatKey.STATISTIC_MOBILE_CHARGING_FULLSCREEN, String.valueOf(mCheckFullScreenFrom),
                    topPkg);
            if (DEBUG) {
                Log.d(TAG, "onFullScreenDetected.全屏不弹");
            }
            break;
        case UNKNOW_TYPE:
        case TYPE_NOT_FULLSCREEN:
            IntentSkip.skipToBatteryCharging(mContext, mCheckFullScreenFrom);
            setIntervalTime();
            break;
        }
        mCheckFullScreenFrom = -1;

    }

    /**
     * 杀掉竞品
     */
    public void killOthers() {
        this.mBgHandler.sendEmptyMessage(BACKGROUND_MSG_KILL_OTHERS);
    }

    public void onPackageAdd(String pkg) {
    }

    public void onPackageRemove(String pkg) {
    }

}
